#include "SHT30.h"

bool SHT30_Init(void)
{
    GpioInit();
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_0, WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA);
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_1, WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL);
    I2cInit(WIFI_IOT_GPIO_IDX_1, 400000);

    WifiIotI2cData I2cData = { 0 };

    uint8_t buffer[2] = {0x21, 0x30};
    I2cData.sendBuf = buffer;
    I2cData.sendLen = 2;
	if(I2cWrite(WIFI_IOT_I2C_IDX_1, (SHT30_DEVICE_ADDRESS << 1) | 0x00, &I2cData) == 0)
    {
		return true;
    }
    else
    {
		return false;
    }
}

bool SHT30_CheckDate(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum)
{
    uint8_t crc = 0xFF;
    uint8_t bit = 0;
    uint8_t byteCtr ;
	const int16_t POLYNOMIAL = 0x131;
    for(byteCtr = 0; byteCtr < nbrOfBytes; ++byteCtr)
    {
        crc ^= (data[byteCtr]);
        for ( bit = 8; bit > 0; --bit)
        {
            if (crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL;
            else crc = (crc << 1);
        }
    }
	
    if(crc == checksum)
    {
		return true;
    }
    else
    {
		return false;
    }	
}

bool SHT30_GetData(float *temp, float *humi)
{
	WifiIotI2cData I2cData = {0};

    uint8_t sBuffer[2] = {0xE0, 0x00};
    I2cData.sendBuf = sBuffer;
    I2cData.sendLen = 2;

    uint8_t rBuffer[6] = {0, 0, 0, 0, 0, 0};
    I2cData.receiveBuf = rBuffer;
    I2cData.receiveLen = 6;

    if(I2cWriteread(WIFI_IOT_GPIO_IDX_1, (SHT30_DEVICE_ADDRESS << 1) | 0x00, &I2cData) == 0)
    {
        uint8_t tmpArray1[3] = {rBuffer[0], rBuffer[1], rBuffer[2]};
        bool result1 = SHT30_CheckDate(tmpArray1, 2, tmpArray1[2]);
        if(result1)
        {
            uint16_t temp_raw = ((uint16_t)rBuffer[0] << 8) | rBuffer[1];
            temp_raw &= ~0x0003;
            *temp = (175 * (float)temp_raw / 65535 - 45);
        }
        uint8_t tmpArray2[3] = {rBuffer[3], rBuffer[4], rBuffer[5]};
        bool result2 = SHT30_CheckDate(tmpArray2, 2, tmpArray2[2]);
        if(result2)
        {
            uint16_t humi_raw = ((uint16_t)rBuffer[3] << 8) | rBuffer[4];	
            humi_raw &= ~0x0003;
            *humi = (100 * (float)humi_raw / 65535);
        }
        return result1 && result2;
    }
    else
    {
        *temp = 0;
        *humi = 0;
        return false;
    }
}
